﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Web;

using Telerik.Cms;
using Telerik.Cms.Web;
using Telerik.Security.Permissions;

namespace Telerik.Sitefinity.Services.Migration
{
	public partial class MigrationExportService : IMigrationExportService
	{
		private void GetPagesListWithParent(Guid parentId, CmsManager cmsManager, List<MigrationPageContentDefinition> output)
		{
			IList childPages = cmsManager.GetPages(parentId);

			foreach (ICmsPage p in childPages)
			{
				MigrationPageContentDefinition mpcd = new MigrationPageContentDefinition();
				mpcd.ParentId = parentId;
				mpcd.Id = p.ID;
				mpcd.ProviderName = cmsManager.Provider.Name;
				output.Add(mpcd);

				GetPagesListWithParent(p.ID, cmsManager, output);
			}
		}

		public Message GetPagesList()
		{
			List<MigrationPageContentDefinition> output = new List<MigrationPageContentDefinition>();

			IDictionary<string, CmsProvider> cmsProviders = CmsManager.Providers;

			foreach (KeyValuePair<string, CmsProvider> cmsProvider in cmsProviders)
			{
				string providerName = cmsProvider.Key;

#if VERSION_BELOW_SP3
				CmsManager cmsManager = new CmsManager();
#else
				CmsManager cmsManager = new CmsManager(providerName);			
#endif

				GetPagesListWithParent(new Guid(SiteMap.RootNode.Key), cmsManager, output);
			}

			MessageVersion ver = OperationContext.Current.IncomingMessageVersion;
			return Message.CreateMessage(ver, "GetPagesListResponse", output);
		}

		public Message GetSinglePage(Message pageDefinitionParam)
		{
			MigrationPageContentDefinition param = pageDefinitionParam.GetBody<MigrationPageContentDefinition>();

#if SITEFINITY_37_SP3PLUS
			CmsManager cmsManager = new CmsManager(param.ProviderName);
#else
			CmsManager cmsManager = new CmsManager();
#endif

			var p = cmsManager.GetPage(param.Id) as ICmsPage;

            var homePage = UrlHelper.HomePage;

			MigrationPageGroup mpg = new MigrationPageGroup();

			foreach (KeyValuePair<int, IPageContent> pageLanguage in p.LanguageVersions)
			{
				var page = pageLanguage.Value as ICmsPage;
				if (page != null)
				{
					var mp = new MigrationPage
					{
						LangID = page.LangID,
						CmsProviderName = page.CmsProvider.Name,
						ContainsUrlSrvc = page.ContainsUrlSrvc,
						DateCreated = page.DateCreated,
						DateModified = page.DateModified,
						DenyAnonymous = page.DenyAnonymous,
						DenyIndexing = page.DenyIndexing,
						Description = page.Description,
						DisableViewState = page.DisableViewState,
						ExternalUrl = page.ExternalUrl,
						Id = page.ID,
						IsHomePage = page.ID == homePage.ID,
						Keywords = page.Keywords,
						MasterPage = page.MasterPage,
						MenuName = page.MenuName,
						Name = page.Name,
						Navigable = page.Navigable,
						Ordinal = page.Ordinal,
						Owner = page.Owner,
						PageType = page.PageType.ToString(),
						ParentId = page.ParentID,
						RequireCaching = page.RequireCaching,
						RequireSsl = page.RequireSSL,
						Status = page.Status.ToString(),
						Theme = page.Theme,
						Title = page.Title,
						Version = page.Version
					};

					if (page.DefaultUrl != null)
					{
						mp.DefaultUrl = page.DefaultUrl.Url;
						if (!String.IsNullOrEmpty(page.DefaultUrl.QueryString))
							mp.DefaultUrl += "?" + page.DefaultUrl.QueryString;
					}
					else
					{
						mp.DefaultUrl = String.Empty;
					}

					if (page.Template != null)
					{
						mp.TemplateId = page.Template.ID;
						mp.TemplateName = page.Template.Name;
					}
					else
					{
						mp.TemplateId = Guid.Empty;
						mp.TemplateName = String.Empty;
					}

					foreach (var url in page.Urls)
					{
						var cmsUrl = url as ICmsUrl;
						if (cmsUrl != null)
						{
							string urlToAdd = cmsUrl.Url;
							if (!String.IsNullOrEmpty(cmsUrl.QueryString))
								urlToAdd = "?" + cmsUrl.QueryString;
							mp.Urls.Add(urlToAdd);
						}
					}

					GetControlsToMigrationCollection(page.Staged.Controls, mp.Controls);

					IDictionary<string, ApplicationPermission> permissions = null;
					ISecured secObj = page as ISecured;
					if (secObj is ISecuredBase)
						permissions = ((ISecuredBase)secObj).GetPermissions("Sitefinity");
					else if (secObj != null)
						permissions = secObj.Permissions;

					if (permissions != null)
					{
						foreach (KeyValuePair<string, ApplicationPermission> permission in permissions)
						{
							MigrationPermission mPerm = new MigrationPermission();
							mPerm.RoleName = permission.Key;
							mPerm.Grant = permission.Value.Grant;
							mPerm.Deny = permission.Value.Deny;

							mp.Permissions.Add(mPerm);
						}
					}

					mpg.Pages.Add(mp);
				}
			}

			MessageVersion ver = OperationContext.Current.IncomingMessageVersion;
			return Message.CreateMessage(ver, "GetSinglePageResponse", mpg);
		}
	}
}
